Supplemental Materials#
For my systematic review on latent Variable modeling approaches, here are some additional plots and data that might be of interest. If you discover any issues, please contact zoe.sandle@donders.ru.nl.
### read in data and activate the environmentimport pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import statsmodels.api as sm
import statsmodels.formula.api as smf
import pandas as pd
import plotly.graph_objects as go
#setting wd to where the data is
import os
os.chdir('C:/Users/U727148/Desktop/DATA/REVIEW/')
df = pd.read_excel('updated_from_cleaned_20250423.xlsx')
df_sankey_models_transformed = pd.read_excel('dfsankeymodels_updated_20250424.xlsx')
LCA_outcomes = pd.read_excel('LCA_outcomes.xlsx')
df_sankey_cups = pd.read_excel('dfsankeycu.xlsx')
df_sankey_beh = pd.read_excel('dfsankey_behavioral_variables.xlsx')
df_sankey_cog = pd.read_excel('df_sankey_cog.xlsx')
df_reports = pd.read_excel('df_reports.xlsx')
Sankey Plots#
In this first plot, the first column represents the general model used in all studies, the second column includes additional specifications (e.g. for factor analysis, whether it was exploratory or confirmatory, or which type of rotation was used). Follow up analyses are shown in the third column. Hovering over each node shows the number of incoming and outgoing flow, hovering over the connections shows the First Author & Year. Each node can be moved around for readability or bundled using box or lasso select. 4
Variables have been exploded, meaning that if a study assessed more than one variable for each of the nodes, its name will show up in multiple parts of the graph.
# 1. Create unique labels
labels = list(pd.concat([
df_sankey_models_transformed['gm'],
df_sankey_models_transformed['mit'],
df_sankey_models_transformed['oa']
]).unique())
# 2. Map labels to indices
label_map = {label: idx for idx, label in enumerate(labels)}
# 3. Define sources, targets, and values
sources = df_sankey_models_transformed['gm'].map(label_map).tolist() + \
df_sankey_models_transformed['mit'].map(label_map).tolist()
targets = df_sankey_models_transformed['mit'].map(label_map).tolist() + \
df_sankey_models_transformed['oa'].map(label_map).tolist()
values = df_sankey_models_transformed['gm_count'].tolist() + \
df_sankey_models_transformed['oa_count'].tolist()
# 4. Generate pastel colors
import random
def pastel_color():
r = lambda: random.randint(100, 255)
return f'rgba({r()},{r()},{r()},0.6)'
label_to_color = {label: pastel_color() for label in labels}
node_color_list = [label_to_color[label] for label in labels]
# 5. Set link colors by source node's color (first half) and middle node (second half)
link_colors = [label_to_color[df_sankey_models_transformed['gm'].iloc[i]]
for i in range(len(df_sankey_models_transformed))] + \
[label_to_color[df_sankey_models_transformed['mit'].iloc[i]]
for i in range(len(df_sankey_models_transformed))]
# 7. Create the figure
fig = go.Figure(data=[go.Sankey(
node=dict(
pad=15,
thickness=20,
line=dict(color="black", width=0.9),
label=labels,
color=node_color_list,
align="left"
),
link=dict(
source=sources,
target=targets,
value=values,
color=link_colors,
customdata=df_sankey_models_transformed['nameyear'].tolist() * 2,
hovertemplate='%{customdata}<extra></extra>'
)
)])
fig.update_layout(
title_text="Sankey Diagram for model types",
font_size=16.5,
width=1500,
height=800,
hovermode='x'
)
fig.show()
fig.write_html("C:/Users/U727148/Latent_Variable_Supplement/sankey_models_plot.html", include_plotlyjs="cdn")
Variable Plots#
In these plots, I am modeling the flow of usage from 1. variable, 2. scale used, 3. type of assessment (self and other report, experimental, observational). This is for the psychopathic traits/CU traits variable, the behavioral variable, and the cognitive variable (for the brain variables, there was not enough data available).
# 1. Create unique labels
labels = list(pd.concat([
df_sankey_cups['p_or_cu'],
df_sankey_cups['scale'],
df_sankey_cups['reporting_type']
]).unique())
# 2. Map labels to indices
label_map = {label: idx for idx, label in enumerate(labels)}
# 3. Define sources, targets, and values
sources = df_sankey_cups['p_or_cu'].map(label_map).tolist() + \
df_sankey_cups['scale'].map(label_map).tolist()
targets = df_sankey_cups['scale'].map(label_map).tolist() + \
df_sankey_cups['reporting_type'].map(label_map).tolist()
values = df_sankey_cups['pcu_count'].tolist() + \
df_sankey_cups['reporttype_count'].tolist()
# 4. Generate pastel colors
import random
def pastel_color():
r = lambda: random.randint(100, 255)
return f'rgba({r()},{r()},{r()},0.6)'
label_to_color = {label: pastel_color() for label in labels}
node_color_list = [label_to_color[label] for label in labels]
# 5. Set link colors by source node's color (first half) and middle node (second half)
link_colors = [label_to_color[df_sankey_cups['p_or_cu'].iloc[i]]
for i in range(len(df_sankey_cups))] + \
[label_to_color[df_sankey_cups['scale'].iloc[i]]
for i in range(len(df_sankey_cups))]
# 7. Create the figure
fig = go.Figure(data=[go.Sankey(
node=dict(
pad=15,
thickness=20,
line=dict(color="black", width=0.9),
label=labels,
color=node_color_list,
align="left"
),
link=dict(
source=sources,
target=targets,
value=values,
color=link_colors,
customdata=df_sankey_models_transformed['nameyear'].tolist() * 2,
hovertemplate='%{customdata}<extra></extra>'
)
)])
fig.update_layout(
title_text="Sankey Diagram for psychopathic/CU traits, scales, and assessment types",
font_size=16.5,
width=1500,
height=800,
hovermode='x'
)
fig.show()
fig.write_html("C:/Users/U727148/Latent_Variable_Supplement/sankey_pcu_plot.html", include_plotlyjs="cdn")
#adding count vars to the behavioral variables based on how many times they appear in the data
#we add a new column to the df_sankey_beh dataframe that counts the number of times each behavioral variable appears in the data
df_sankey_beh['b_count'] = df_sankey_beh['behavioral_variable'].map(df_sankey_beh['behavioral_variable'].value_counts())
df_sankey_beh['ss_count'] = df_sankey_beh['scale_summarized'].map(df_sankey_beh['scale_summarized'].value_counts())
df_sankey_beh['a_count'] = df_sankey_beh['behavioral_assessment'].map(df_sankey_beh['behavioral_assessment'].value_counts())
df_sankey_beh['at_count'] = df_sankey_beh['behavioral_assessment_type'].map(df_sankey_beh['behavioral_assessment_type'].value_counts())
Behavioral Variables#
In this plot, we see the behavioral variables, the scale they were investigated with, and reporting types. Because of the diversity of scales, I also added a node where I summarize the type of scale for easier viewing between the scale and the reporting type.
#Sankey plot for behavioral variables
# 1. Create unique labels
labels = list(pd.concat([
df_sankey_beh['behavioral_variable'],
df_sankey_beh['behavioral_assessment'],
df_sankey_beh['scale_summarized'],
df_sankey_beh['behavioral_assessment_type'],
]).unique())
# 2. Map labels to indices
label_map = {label: idx for idx, label in enumerate(labels)}
# 3. Define sources, targets, and values
sources = df_sankey_beh['behavioral_variable'].map(label_map).tolist() + \
df_sankey_beh['behavioral_assessment'].map(label_map).tolist() + \
df_sankey_beh['scale_summarized'].map(label_map).tolist()
targets = df_sankey_beh['behavioral_assessment'].map(label_map).tolist() + \
df_sankey_beh['scale_summarized'].map(label_map).tolist() + \
df_sankey_beh['behavioral_assessment_type'].map(label_map).tolist()
values = df_sankey_beh['b_count'].tolist() + \
df_sankey_beh['ss_count'].tolist() + \
df_sankey_beh['at_count'].tolist()
# 4. Generate pastel colors
import random
def pastel_color():
r = lambda: random.randint(100, 255)
return f'rgba({r()},{r()},{r()},0.6)'
label_to_color = {label: pastel_color() for label in labels}
node_color_list = [label_to_color[label] for label in labels]
# 5. Set link colors by source node's color (first) and middle nodes (second) and last node
link_colors = [label_to_color[df_sankey_beh['behavioral_variable'].iloc[i]]
for i in range(len(df_sankey_beh))] + \
[label_to_color[df_sankey_beh['scale_summarized'].iloc[i]]
for i in range(len(df_sankey_beh))] + \
[label_to_color[df_sankey_beh['behavioral_assessment_type'].iloc[i]]
for i in range(len(df_sankey_beh))]
# 7. Create the figure
fig = go.Figure(data=[go.Sankey(
node=dict(
pad=15,
thickness=20,
line=dict(color="black", width=0.9),
label=labels,
color=node_color_list,
align="left"
),
link=dict(
source=sources,
target=targets,
value=values,
color=link_colors,
customdata=df_sankey_models_transformed['nameyear'].tolist() * 5,
hovertemplate='%{customdata}<extra></extra>'
)
)])
fig.update_layout(
title_text="Sankey Diagram for variables, scales, and assessment types",
font_size=16.5,
width=1700,
height=1200,
hovermode='x'
)
fig.show()
fig.write_html("C:/Users/U727148/Latent_Variable_Supplement/sankey_behavior_plot.html", include_plotlyjs="cdn")
Cognitive variables#
This is an overview plot for the studies using cognitive variables (which of course is only 40.5% of studies actually did). Left is the variable, in the middle is the name of the scale or test used, and left is the type of report.
#Making the sankey plot for cognitive variables
# 1. Create unique labels
labels = list(pd.concat([
df_sankey_cog['cv'],
df_sankey_cog['ca'],
df_sankey_cog['cat']
]).unique())
# 2. Map labels to indices
label_map = {label: idx for idx, label in enumerate(labels)}
# 3. Define sources, targets, and values
sources = df_sankey_cog['cv'].map(label_map).tolist() + \
df_sankey_cog['ca'].map(label_map).tolist()
targets = df_sankey_cog['ca'].map(label_map).tolist() + \
df_sankey_cog['cat'].map(label_map).tolist()
values = df_sankey_cog['c_count'].tolist() + \
df_sankey_cog['cat_count'].tolist()
# 4. Generate pastel colors
import random
def pastel_color():
r = lambda: random.randint(100, 255)
return f'rgba({r()},{r()},{r()},0.6)'
label_to_color = {label: pastel_color() for label in labels}
node_color_list = [label_to_color[label] for label in labels]
# 5. Set link colors by source node's color (first half) and middle node (second half)
link_colors = [label_to_color[df_sankey_cog['cv'].iloc[i]]
for i in range(len(df_sankey_cog))] + \
[label_to_color[df_sankey_cog['ca'].iloc[i]]
for i in range(len(df_sankey_cog))]
# 7. Create the figure
fig = go.Figure(data=[go.Sankey(
node=dict(
pad=15,
thickness=20,
line=dict(color="black", width=0.9),
label=labels,
color=node_color_list,
align="left"
),
link=dict(
source=sources,
target=targets,
value=values,
color=link_colors,
customdata=df_sankey_cog['nameyear'].tolist() * 2,
hovertemplate='%{customdata}<extra></extra>'
)
)])
fig.update_layout(
title_text="Sankey Diagram for cognitive variables, assessments, and assessment types",
font_size=16.5,
width=1700,
height=1200,
hovermode='x'
)
fig.show()
fig.write_html("C:/Users/U727148/Latent_Variable_Supplement/sankey_cog_plot.html", include_plotlyjs="cdn")
Reporting types plot#
In this plot, we can see how the reporting types feed into each other for all the variables (answering the question whether studies only using self report for one of the variables are more likely to use self report for other variables as well). In contrast to the other dataframes, the reporting types are not exploded, meaning that studies using multiple reporting types are not fed into multiple measures. The left column is the P/CU trait column, the middle the behavioral and the left column contains the cognitive variable reporting types. For readability, some variable names have been abbreviated (in the behavioral: self report = s, other report = o; in the cognitive: self report = self, other report = other).
# 1. Create unique labels
labels = list(pd.concat([
df_reports['assessment_type'],
df_reports['cognitive_assessment_type'],
df_reports['behavioral_assessment_type'],
]).unique())
# 2. Map labels to indices
label_map = {label: idx for idx, label in enumerate(labels)}
# 3. Define sources, targets, and values
sources = df_reports['assessment_type'].map(label_map).tolist() + \
df_reports['behavioral_assessment_type'].map(label_map).tolist()
targets = df_reports['behavioral_assessment_type'].map(label_map).tolist() + \
df_reports['cognitive_assessment_type'].map(label_map).tolist()
values = df_reports['assessment_type_count'].tolist() + \
df_reports['cognitive_assessment_type_count'].tolist()
# 4. Generate pastel colors
import random
def pastel_color():
r = lambda: random.randint(100, 255)
return f'rgba({r()},{r()},{r()},0.6)'
label_to_color = {label: pastel_color() for label in labels}
node_color_list = [label_to_color[label] for label in labels]
# 5. Set link colors by source node's color (first half) and middle node (second half)
link_colors = [label_to_color[df_reports['assessment_type'].iloc[i]]
for i in range(len(df_reports))] + \
[label_to_color[df_reports['behavioral_assessment_type'].iloc[i]]
for i in range(len(df_reports))]
# 7. Create the figure
fig = go.Figure(data=[go.Sankey(
node=dict(
pad=15,
thickness=20,
line=dict(color="black", width=0.9),
label=labels,
color=node_color_list,
align="left"
),
link=dict(
source=sources,
target=targets,
value=values,
color=link_colors,
customdata=df_reports['nameyear'].tolist() * 2,
hovertemplate='%{customdata}<extra></extra>'
)
)])
fig.update_layout(
title_text="Reporting types for P/CU traits, cognitive assessments, and behavioral assessments",
font_size=16.5,
width=1700,
height=1200,
hovermode='x'
)
fig.show()
fig.write_html("C:/Users/U727148/Latent_Variable_Supplement/sankey_reports_plot.html", include_plotlyjs="cdn")
df_reports_corr = df_reports[['assessment_type_count', 'cognitive_assessment_type_count', 'behavioral_assessment_type_count']].copy()
corr = df_reports_corr.corr()
corr
| assessment_type_count | cognitive_assessment_type_count | behavioral_assessment_type_count | |
|---|---|---|---|
| assessment_type_count | 1.000000 | 0.107188 | 0.276320 |
| cognitive_assessment_type_count | 0.107188 | 1.000000 | 0.372502 |
| behavioral_assessment_type_count | 0.276320 | 0.372502 | 1.000000 |
So we also see that how many assessments types were used correlate fairly substantially for the behavioral variable with both the P/CU variable (weakly) and the cognitive variable (medium)
Outcomes of Latent Class Analysis Overview#
Here is a simple table with an overview of Latent Class Analysis/Latent Profile Analysis Solutions. Described are the Study Identifiers such as name of the first author, year, name of the study. what follows is which variables made up predictor(s) and how they were measured, outcomes, name and distribution of classes and some additional explanations.
LCA_outcomes
| nameyear | region | age_mean | sample size | gender distr. (% f) | number_of_predictors | institutional_sample | psychopathic or CU trait (in brackets if not predictor) | predictor (Scale) | Unnamed: 9 | predictor (additional variables) | outcome variables | model | solution (no. of groups and distribution) | group names | comments | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Ciesenski 2024 | north america | 35.24 | 504 | 55.20 | 7 | 0 | psychopathic traits | Psychopathy Checklist: Revised (PCL-R) | self report | anger; hostility; emotion liability; emotion i... | psychiatric comorbidity, aggression, self-harm... | latent class analysis | 4 | 36.11% low emotion dysregulation and impulsivi... | mixture salsa/qualitative. CU-traits formed it... |
| 1 | Neumann 2024 | north america | 16.7 | 409 | 19.40 | 1 | 1 | CU traits | Proposed Specifiers for Conduct Disorder Scale... | other report | NaN | Externalizing Behavior, Criminality, Behaviora... | latent profile analysis | 4 | 34% general group; 31% externalizing group; 24... | Facets of the PSCD are: grandiose-manipulative... |
| 2 | Roy 2023 | north america | 29.9 | 2570 | 0.00 | 1 | 1 | psychopathic traits | Psychopathy Checklist: Revised (PCL-R) | self report | NaN | Behavioral Inhibition/Activation, Criminal His... | latent profile analysis | 4 | 40% externalizing, 36% psychopathic, 18% gener... | In a forensic sample, these four different gro... |
| 3 | Brislin 2024 | north america | 9.92 | 11552 | 45.30 | 2 | 0 | CU traits | ABCD cu trait scale (SDQ/CBCL) | other report | impulsivity (BIS/BAS, UPPS) | Externalizing Behavior | latent profile analysis | 3 | 35.89% low impulsivity but high CU traits, 52.... | groups differ significantly on externalizing b... |
| 4 | Shields 2024 | north america | 9.81 | 342 | 53.22 | 1 | 0 | CU traits | Inventory of Callous-Unemotional Traits (ICU) | other report | irritability, withdrawal, sadness, positive em... | aggression, CU-traits | latent profile analysis | 0 | no solution | results suggest that reactive aggression is un... |
| 5 | Hare 2022 | south america | 51.227 | 411 | 0.00 | 1 | 1 | psychopathic traits | Psychopathy Checklist: Revised (PCL-R) | interview | NaN | Criminal Record | latent profile analysis | 4 | 21% Prototypic Psychopathy; 26.2% Callous-Conn... | Study compared community, "normal" offenders, ... |
| 6 | Colins 2022 | europe | 16.2 | 302 | 100.00 | 1 | 1 | psychopathic traits | Antisocial Process Screening Device (APSD) | self report | NaN | Criminal Record | latent profile analysis | 2 | 74.2% low scoring, 25.8% high scoring | Study examined likelihood of future criminalit... |
| 7 | Gong 2022 | asia | 45.43 | 279 | 100.00 | 1 | 1 | psychopathic traits | Levenson Self Report Psychopathy Rating scale ... | self report | NaN | Aggression | latent profile analysis | 3 | 66.7% medium psychopathy, 27.6% low psychopath... | None of the groups were high on calloussness i... |
| 8 | Voulgaridou 2022 | europe | 14.04 | 2207 | 52.80 | 1 | 0 | (CU traits) | Aggression (Relational Aggression Scale) | self report | NaN | CU-traits; hostile attribution bias | latent transition analysis | 3 | 67.5% low; 24.7% medium; 7.8% high | Salsa. The three profiles differed (in expecte... |
| 9 | Willoughby 2022 | north america | 7.2 | 138 | 32.00 | 1 | 0 | (CU traits) | ADHD and ODD behavior (clinical assessment) | other report | NaN | academic productivity, impairment, and social ... | latent profile analysis | 3 | 17% high ADHD; 49% low ADHD and ODD; 34% high ... | significant differences between groups on acad... |
| 10 | Michielsen 2022 | europe | 14.77 | 679 | 51.98 | 2 | 0 | CU traits | Youth Psychopathic Traits Inventory (YPI) | self report | Anxiety | Delinquency | latent profile analysis | 3 | 74% reference (average) group); 14% high CU; 1... | In this community sample, the combined anxious... |
| 11 | Lopez-Romero 2021 | europe | 4.25 | 2247 | 48.60 | 1 | 0 | CU/psychopathic traits | Child Problematic Traits Inventory (CPTI) | other report | NaN | Conduct Problems, Re- and Proactive Aggression... | latent profile analysis | 5 | 39.2% control class; 34.8% high need for stim... | Differences in profiles on both Parent and tea... |
| 12 | Harrop 2021 | north america | 27.08 | 840 | 18.80 | 1 | 0 | psychopathic traits | Levenson Self Report Psychopathy Rating scale ... | self report | NaN | Aggression, Sensation Seeking, Anger, Stoicism... | latent profile analysis | 4 | 43.9% Average; 43.3% Low. 4.6% Callous (low on... | The high profile scored consistently higher on... |
| 13 | Gillespie 2021 | north america | 30 | 840 | 42.50 | 1 | 1 | psychopathic traits | PCL:SV | other report | NaN | Anger (cognitive/behavioral/arousal); Depressi... | latent profile analysis | 3 | female: 49% low; 14% high (callous aggressive)... | Different solutions for men and women, in wome... |
| 14 | Gillespie 2021 | north america | 30 | 840 | 42.50 | 1 | 1 | psychopathic traits | PCL:SV | other report | NaN | Anger (cognitive/behavioral/arousal); Depressi... | latent profile analysis | 4 | male: 34% low; 12% high (callous aggressive); ... | Different solutions for men and women, in wome... |
| 15 | Breaux 2020 | north america | 8.92 | 222 | 19.80 | 2 | 0 | psychopathic traits | Child Psychopathy Scale (CPS) | other report | disruptive behavior disorder rating scale | Calloussness; Impairment; ADHD, ODD, CD symptoms | latent profile analysis | 3 | Parent-ratings: 26% low, 58% moderate, 16% high | The low profiles were lower on calloussness an... |
| 16 | Breaux 2020 | north america | 8.92 | 222 | 19.80 | 2 | 0 | psychopathic traits | Child Psychopathy Scale (CPS) | other report | disruptive behavior disorder rating scale | Calloussness; Impairment; ADHD, ODD, CD symptoms | latent profile analysis | 4 | Teacher-ratings: 36% low, 28% moderate, 26% no... | The low profiles were lower on calloussness an... |
| 17 | Maneiro 2020 | europe | 20.55 | 316 | 51.30 | 1 | 0 | psychopathic traits | Dark Triad Dirty Dozen | self report | NaN | Aggression, Substance Use, Risk, Internet Use | latent profile analysis | 5 | 32.4% Narcissistic; 17.7% Macchiavellian/Narci... | Groups did not differ significantly in substan... |
| 18 | Wang 2020 | asia | 36.03 | 3375 | 0.00 | 1 | 1 | psychopathic traits | Levenson Self Report Psychopathy Rating scale ... | self report | NaN | Aggression | latent profile analysis | 4 | 59.9% low psychopathy; 19.5% moderate psychop... | Classes differ on re- and proactive aggression... |
| 19 | Lehmann 2019 | europe | 36.2 | 215 | 0.00 | 1 | 1 | psychopathic traits | Psychopathy Checklist: Revised (PCL-R) | interview | NaN | Criminal Record | latent profile analysis | 4 | 48.8% general offenders; 26.5% "Sociopaths" (a... | Groups differed on recidivism rates and types.... |
| 20 | Piehler 2019 | north america | 14.8 | 197 | 42.60 | 1 | 1 | (CU traits) | Self Control, Executive Function (DCCS, Flanke... | experimental; other report | NaN | CU-traits; criminal record & conduct problems | latent profile analysis | 3 | 10.4% cognitively inflexible; 36.1% adaptive; ... | groups differed significantly on measures of C... |
| 21 | Waller 2019 | north america | not reported | 1170 | 0.00 | 2 | 1 | psychopathic traits | Psychopathy Checklist: Youth Version (PCL:YV) | interview | Anxiety | Alcohol and Marijuana Use | latent class analysis | 4 | 39% low; 21% high anxiety/low psychopathy; 26%... | groups did not differ significantly on substan... |
| 22 | Goulter 2019 | oceania | 19.02 | 101 | 100.00 | 1 | 0 | psychopathic traits | Psychopathic Personality Inventory (PPI) | self report | NaN | Aggression; Comorbidities | latent profile analysis | 2 | 63.33% Primary; 36.7% Secondary | Secondary group characterized by high anxiety... |
| 23 | Colins 2018 | europe | 16.7 | 847 | 0.00 | 2 | 1 | psychopathic traits | Youth Psychopathic Traits Inventory (YPI) | self report | Anxiety | Aggression; substance use; Conduct Problems; C... | latent profile analysis | 4 | 61.5% low/baseline; 21.6% moderate psychopathy... | Significant differences on Conduct Problems an... |
| 24 | Driessen 2018 | north america | 31.31 | 576 | 0.00 | 1 | 1 | psychopathic traits | Self Report Psychopathy Scale (SRP) | self report | NaN | Violent Crime, Aggression, Disinhibition, Nega... | latent profile analysis | 4 | 44.4% general offenders; 21% non-antisocial ps... | IA group scored highest on violent crrime, non... |
| 25 | Boduszek 2017 | europe | 34.26 | 1126 | 0.00 | 1 | 1 | psychopathic traits | Psychopathic Personality Traits Scale (PPTS) | self report | NaN | Criminal Behavior | latent profile analysis | 5 | 44.6% low; 20.8% high interpersonal manipulati... | Comparison of different crime types with perso... |
| 26 | Fanti 2017 | north america | 3 | 1167 | 48.30 | 4 | 0 | CU traits | Achenbach System of Empirically Based Assessme... | other report | Externalizing problems, anxiety, depression | CU traits, externalizing, internalizing 12 yea... | latent profile analysis | 4 | 68.1% low; 10.7% high on Ext/Int, low callous... | Groups were stable between ages 3 and 15. |
| 27 | Colins 2017 | europe | 22.15 | 2500 | 52.60 | 1 | 0 | psychopathic traits | Youth Psychopathic Traits Inventory (YPI) | self report | NaN | Aggression, substance Use, Comorbidities, Abus... | latent profile analysis | 5 | 66% low/non-psychopathic; 12% high/psychopathi... | Slight gender differences (males very slightly... |
| 28 | Krstic 2017 | north america | 37.83 | 958 | 0.00 | 1 | 1 | psychopathic traits | Psychopathy Checklist: Revised (PCL-R) | interview | NaN | Sexual Violence | latent profile analysis | 4 | 44% general offender; 23% Sociopathic (high an... | Antisocial/personality factors predict sexual ... |
| 29 | Ray 2016 | north america | 15.29 | 1216 | 0.00 | 2 | 1 | (CU traits) | delinquency; substance use (study specific scale) | self report | NaN | CU traits (measured by ICU), IQ, neighbourhood... | latent class analysis | 3 | delinquency: fighter only 67%; minor crimes: 2... | CU traits and impulsivity contributed to delin... |
| 30 | Wall 2016 | europe | 9.38 | 1366 | 53.60 | 2 | 0 | CU traits | Inventory of Callous-Unemotional Traits (ICU) | other report | Conduct Problems | Executive Function/Impulsivity, Parental Invol... | latent profile analysis | 5 | 67.2% low risk; 9.4% high CU traits; 8.4% mode... | Groups significantly differed on EF/Impulsivit... |
| 31 | Andrade 2016 | north america | 8.8 | 208 | 21.60 | 3 | 0 | CU traits | Callous-Unemotional Traits—Brief Measure (3 it... | other report | Impulsive Behavior, Externalizing Behavior as ... | Aggression | latent class analysis | 5 | 35.6% low; 30.8% low-moderate; 21.6% moderate;... | significant differences in re- and proactive a... |
| 32 | Mokros 2015 | north america | 30.9 | 497 | 0.00 | 1 | 1 | psychopathic traits | Psychopathy Checklist: Revised (PCL-R) | interview | NaN | ASPD symptoms | latent profile analysis | 3 | 73.2% consistently high; 19.3% high interperso... | Groups differed significantly on total ASPD sy... |
| 33 | Dhingra 2015 | north america | 29.86 | 871 | 57.60 | 1 | 1 | psychopathic traits | Psychopathy Checklist: Revised (PCL-R) | interview | NaN | Criminal Behavior | latent class analysis | 4 | 26.4% High overall; 16% moderate; 31.3% antiso... | Psychopathic Classes were more likely to be a)... |
| 34 | Fanti 2013 | europe | 14.02 | 1674 | 50.10 | 2 | 0 | CU traits | Inventory of Callous-Unemotional Traits (ICU) | other report | Conduct Problems | Inattention/Impulsivity/Hyperactivity, Gender,... | latent profile analysis | 5 | 48.7% low risk; 33.8% average; 6.9% low CP/hig... | Groups higher on CP scored higher on Hyperacti... |
| 35 | Fanti 2013 | europe | 16 | 2306 | 49.69 | 3 | 0 | CU traits | Inventory of Callous-Unemotional Traits (ICU) | self report | Conduct Problems, Anxiety | Aggression; Impulsivity; Sensation Seeking, Se... | latent profile analysis | 4 | 80.5% low risk; 8.9% anxious; 7.8% primary CU;... | Differences on aggression (S-CU>P-CU>A>L), an... |
| 36 | Nijhof 2011 | europe | 15.76 | 214 | 47.20 | 1 | 1 | psychopathic | Youth Psychopathic Traits Inventory (YPI) | self report | NaN | Problem Behavior (Int/Ext), Delinquency, Subst... | latent class analysis | 3 | 51% low, 38.8% Impulsive; 10.2% Psychopathy-like | Bit of a salsa effect. Significant effect on a... |
As a tentative interpretation, it seems to me that group solutions of 3 mostly result in spectrum driven solution (‘salsa’ effect), meaning that there is a low, middle and high group that are not or only minimally different in a qualitative way. Four and five class solutions result mostly in qualitatively different profiles, with usually one large reference/low CU/psychopathic traits group, one that is consistently high, and two that are higher on only affective or behavioral traits. When there is variation, this occurs more on the behavioral traits. Often, outcomes also quantitatively and qualitatively differ between these groups.
Another conclusion is that while different facets of psychopathy/CU traits exist on a spectrum and thus psychopathic traits themselves are a spectrum as well, they don’t always neatly combine in a linear way. While the consistently high traits group often differ the most on aggression from the consistently low groups, groups high only behavioral/CU traits differ from the other groups in quantitative and qualitative ways (see e.g. involvement in different criminal activities or different cognitive outcomes). There was only one study on our dataset that predicted offense types and CU traits from cognitive variables (Piehler, 2019). The authors in this study draw the conclusion that both cognitively inflexible and emotionally disregulated youth tend to exhibit more conduct problems and externalizing behaviors, but differ in both severity and, crucially, in type. They suggest that there might be different developmental pathways leading to disruptive behavior disorders, that may also result in different behavioral subtypes.
We draw some tentative recommendations:
When performing LCA/LPA with psychopathic/CU traits as a sole predictor, one should aim for a class solution of >= 4. This gives a more qualitatively meaningful solution. If a solution of 2 or 3 is strongly preferred, then a linear regression might be indicated instead to actually cover the entire spectrum of the scale.
When performing LCA/LPA with multiple predictors, this recommendation can be relaxed slightly, though the statistical indicators may favor a group solution with 4+ groups anyway.
There is currently and underutilization of cognitive variables as predictors
Considering the wider project and studies utilizing other modeling approaches such as factor analysis and growth analysis (see poster):
Generally, person-centered approaches such as LCA/LPA find more (meaningful) group solutions than variable centered ones (growth models find more than LPA still). This is a good indicator that these approaches may be more adept at capturing the very real heterogeneity of how these variables tend to present (in patients/the community) and their outcomes. However, all of these approaches run under the assumption of linearity. It is quite likely though (and the data presented here support this idea as well) that associations are not linear. We should try to find some modeling approaches that do not work on linear assumptions.